/*
 * Copyright (C) 2008 Apple Computer, Inc.  All rights reserved.
 * Copyright (C) 2012 Sony Computer Entertainment Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef WebView_h
#define WebView_h

#include "WebPoint.h"
#include "WebRect.h"
#include "WebString.h"
#include <manx/KeyboardEvent.h>
#include <manx/LoadTypes.h>
#include <manx/NetworkProfile.h>
#include <manx/TouchEvent.h>
#include <manx/X509.h>
#include <webkit/WebViewHitTestResult.h>
#include <webkit/WebViewJavaScriptObject.h>
#include <webkit/WebViewManager.h>
#include <webkit/WebViewSettings.h>

enum ScrollEventType {
    ScrollEventTypeUndefined = -1,

    SCROLL_EVENT_UP,
    SCROLL_EVENT_DOWN,
    SCROLL_EVENT_LEFT,
    SCROLL_EVENT_RIGHT,
    SCROLL_EVENT_TOP,
    SCROLL_EVENT_BOTTOM,
    SCROLL_EVENT_PAGE_UP,
    SCROLL_EVENT_PAGE_DOWN,
    SCROLL_EVENT_SET_POSITION,
    SCROLL_EVENT_ZOOM_IN,
    SCROLL_EVENT_ZOOM_OUT,

    ScrollEventTypeCount
};

enum MouseEventType {
    MouseEventTypeUndefined = -1,

    MOUSE_EVENT_MOVED,
    MOUSE_EVENT_PRESSED,
    MOUSE_EVENT_RELEASED,

    MouseEventTypeCount
};

enum MouseButtonType {
    MouseButtonTypeUndefined = -1,

    MOUSE_BUTTON_NONE,
    MOUSE_BUTTON_LEFT,
    MOUSE_BUTTON_MIDDLE,
    MOUSE_BUTTON_RIGHT,
    MOUSE_WHEEL_UP,
    MOUSE_WHEEL_DOWN,

    MouseButtonTypeCount
};

enum KeyDefaultBehavior {
    KeyDefaultBehaviorNone,
    KeyDefaultBehaviorScroll,
    KeyDefaultBehaviorCursorNavigation,
};

namespace WebKit {

class WebView;

enum FocusedNodeType {
    FocusedNodeUnknown,
    FocusedNodeText,
    FocusedNodePassword,
    FocusedNodeNumber,
    FocusedNodeTel,
    FocusedNodeEMail,
    FocusedNodeURL,
    FocusedNodeSearch,
};

struct InputMethodInfo {
    FocusedNodeType type;
    WebString title;
    WebString value;
    WebRect rect;
    bool isMultiple;
};

struct WebViewGeolocationPosition {
    double m_timestamp;
    double m_latitude;
    double m_longitude;
    double m_accuracy;
    double m_altitude;
    double m_altitudeAccuracy;
    double m_heading;
    double m_speed;

    bool m_canProvideLatitude;
    bool m_canProvideLongitude;
    bool m_canProvideAccuracy;
    bool m_canProvideAltitude;
    bool m_canProvideAltitudeAccuracy;
    bool m_canProvideHeading;
    bool m_canProvideSpeed;
};

struct WebViewCreateParam {
    int m_width;
    int m_height;
    void* m_pool;
    void* m_painter;
    bool m_enableGeolocation;
};

class WebViewClient {
public:
    virtual ~WebViewClient() { }
    virtual WebView* createWindow(const char* url, int width, int height, bool isScript) = 0;
    virtual void closeWindowSoon() = 0;
    virtual void runJavaScriptAlert(WebString text) = 0;
    virtual bool runJavaScriptConfirm(WebString text) = 0;
    virtual bool runJavaScriptPrompt(WebString text, WebString defaultValue, WebString& result) = 0;
    virtual void didViewportChanged(float initialScale, float maximumScale, float minimumScale, bool userScalable) = 0;
    virtual void didContentSizeChanged(int width, int height) = 0;
    virtual void didUpdateDrawing(const unsigned char* buffer, int size) = 0;
    virtual void didFocusedNodeChanged() = 0;
    virtual void didCommitLoad() = 0;
    virtual void runOpenPanel() = 0;
    virtual void setCursor(int type) = 0;
    virtual void delegatedScrollRequested(WebPoint) = 0;
    virtual void setInputMethodState(bool enabled) = 0;
    virtual bool httpAuthenticationChallenge(WebString siteUrl, WebString message, WebString& user, WebString& password) = 0;
    virtual void didLocationChanged(WebString url) = 0;
    virtual void didReceiveTitle(WebString title) = 0;
    virtual bool verifyCertificate(int sslError, Manx::X509chain*) = 0;
    virtual void didLoadFailed(int error, WebString domain, WebString url, WebString localizedDescription) = 0;
    virtual bool decidePolicyForNavigationAction(WebString url, int navigationType) = 0;
    virtual void notifyUnsupportScheme(WebString url) = 0;
    virtual bool decidePolicyForNavigationWarning(int warningType) = 0;
    virtual void notifyLoadStarted(void* frame) = 0;
    virtual void notifyLoadProgress(float progress) = 0;
    virtual void notifyLoadSecurityStatus(int securityStatus) = 0;
    virtual void notifyLoadFinished() = 0;
    virtual void notifyHistoryChanged(bool canGoBack, bool canGoForward) = 0;
    virtual void startDownload(WebString url, WebString mimeType) = 0;
    virtual void didFunctionCalled(WebViewJavaScriptObjectDelegate&, int& returnType, double& returnFloat, WebString& returnString) = 0;
    virtual void didWindowObjectCleared(void* frame, void* context, void* windowObject) = 0;
    virtual void showPopupMenu(int itemCount, int selectedItem, bool multiple) = 0;
    virtual void popupMenuItem(WebString item, bool selected, bool enabled) = 0;
    virtual void hidePopupMenu() = 0;
    virtual void setCursorPosition(WebPoint) = 0;
    virtual void startGeolocationUpdating() = 0;
    virtual void stopGeolocationUpdating() = 0;
    virtual void requestGeolocationPermission(WebString origin) = 0;
    virtual void cancelGeolocationPermissionRequest(WebString origin) = 0;
};

class WebView {
public:
    static WebView* create(WebViewClient&);
    virtual ~WebView() { }

    virtual void create(WebViewCreateParam&) = 0;
    virtual void drawRect(float x, float y, float w, float h, void* data, unsigned dataSize) = 0;
    virtual void setClipRect(int x, int y, int w, int h, bool pending) = 0;
    virtual void getClipRect(int* x, int* y, int* w, int* h) = 0;
    virtual void sendMouseEvent(MouseEventType, MouseButtonType, int x, int y) = 0;
    virtual bool sendKeyEvent(Manx::KeyboardEvent&, KeyDefaultBehavior) = 0;
    virtual bool sendTouchEvent(const Manx::TouchEvent*) = 0;
    virtual void sendGestureEvent(unsigned type, int x, int y) = 0;
    virtual void loadURL(const char *url) = 0;
    virtual void loadHTML(const char *html, const char *baseUrl) = 0;
    virtual void loadData(const char *data, unsigned long dataLen, const char *mimetype, const char *encoding, const char *baseUrl) = 0;
    virtual void loadArchive(const char *buf, unsigned long bufLen, const char *url) = 0;
    virtual void applyClipRect() = 0;
    virtual bool updateClipRect(int x, int y, int w, int h, bool pending) = 0;
    virtual void setUserAgent(const char*) = 0;
    virtual const char* userAgent() = 0;
    virtual void overflowScroll(int, int) = 0;
    virtual void reload() = 0;
    virtual void stop() = 0;
    virtual void goBack() = 0;
    virtual void goForward() = 0;
    virtual void increaseTextSize() = 0;
    virtual void decreaseTextSize() = 0;
    virtual void resetTextSize() = 0;
    virtual void setComposition(const char *compositionString, unsigned underlineFrom, unsigned underlineTo) = 0;
    virtual void cancelComposition() = 0;
    virtual void confirmComposition(const char *compositionText, unsigned caretIndex) = 0;
    virtual void exitComposition() = 0;
    virtual void clearText() = 0;
    virtual void hitTest(Manx::Point& hitPoint, WebViewHitTestResult&, bool& elementForm) = 0;
    virtual void setUploadFile(const char* path, const char* name) = 0;
    virtual void setSelectedItemsPopupMenu(int index, bool isEnd) = 0;
    virtual void getItemPopupMenu(int index) = 0;
    virtual void releaseTiles() = 0;
    virtual void setDefaultLayoutWidth(int) = 0;
    virtual bool getImageInfoHit(WebString& url, const char*& data, unsigned& size) = 0;
    virtual void setJavaScriptObj(WebViewJavaScriptObject*) = 0;
    virtual WebSettings& settings() = 0;
    virtual void getInputMethodInfo(InputMethodInfo&) = 0;
    virtual void setCaretVisible(bool) = 0;
    virtual bool isProcessingUserGesture() = 0;
    virtual void setGeolocationPermission(const char* origin, bool isAllowed) = 0;
    virtual void updateGeolocationPosition(const WebViewGeolocationPosition*) = 0;
};

}

namespace MXGlue {

enum HtmlEventType {
    HtmlEventTypeUndefined = -1,

    HTML_INPUT_ELEMENT_SET_VALUE,

    HtmlEventTypeCount
};

enum KeyEventType {
    KeyEventTypeUndefined = -1,

    KEY_EVENT_PRESSED,
    KEY_EVENT_RELEASED,

    KeyEventTypeCount
};

enum KeyType {
    KeyTypeUndefined = -1,

    KEY_A,
    KEY_B,
    KEY_C,
    KEY_D,
    KEY_E,
    KEY_F,
    KEY_G,
    KEY_H,
    KEY_I,
    KEY_J,
    KEY_K,
    KEY_L,
    KEY_M,
    KEY_N,
    KEY_O,
    KEY_P,
    KEY_Q,
    KEY_R,
    KEY_S,
    KEY_T,
    KEY_U,
    KEY_V,
    KEY_W,
    KEY_X,
    KEY_Y,
    KEY_Z,
    KEY_1,
    KEY_2,
    KEY_3,
    KEY_4,
    KEY_5,
    KEY_6,
    KEY_7,
    KEY_8,
    KEY_9,
    KEY_0,

    KEY_F1,
    KEY_F2,
    KEY_F3,
    KEY_F4,
    KEY_F5,
    KEY_F6,
    KEY_F7,
    KEY_F8,
    KEY_F9,
    KEY_F10,
    KEY_F11,
    KEY_F12,

    KEY_ACCENT,
    KEY_BACKSLASH,
    KEY_BACKSPACE,
    KEY_CAPS_LOCK,
    KEY_COMMA,
    KEY_DELETE,
    KEY_DOWN_ARROW,
    KEY_END,
    KEY_ENTER,
    KEY_EQUAL,
    KEY_ESC,
    KEY_HENKAN,
    KEY_HOME,
    KEY_INSERT,
    KEY_KANA,
    KEY_KANJI,
    KEY_LEFT_ARROW,
    KEY_LEFT_BRACKET,
    KEY_MINUS,
    KEY_MUHENKAN,
    KEY_PAGE_DOWN,
    KEY_PAGE_UP,
    KEY_PAUSE,
    KEY_PERIOD,
    KEY_PRINTSCREEN,
    KEY_QUOTATION,
    KEY_RIGHT_ARROW,
    KEY_RIGHT_BRACKET,
    KEY_SCROLL_LOCK,
    KEY_SEMICOLON,
    KEY_SLASH,
    KEY_SPACE,
    KEY_TAB,
    KEY_UP_ARROW,

    KEY_NUMPAD_1,
    KEY_NUMPAD_2,
    KEY_NUMPAD_3,
    KEY_NUMPAD_4,
    KEY_NUMPAD_5,
    KEY_NUMPAD_6,
    KEY_NUMPAD_7,
    KEY_NUMPAD_8,
    KEY_NUMPAD_9,
    KEY_NUMPAD_0,
    KEY_NUMPAD_ASTERISK,
    KEY_NUMPAD_ENTER,
    KEY_NUMPAD_MINUS,
    KEY_NUMPAD_NUMLOCK,
    KEY_NUMPAD_PERIOD,
    KEY_NUMPAD_PLUS,
    KEY_NUMPAD_SLASH,

    KEY_CARET_MOVE_LEFT,
    KEY_CARET_MOVE_RIGHT,
    KEY_CARET_MOVE_UP,
    KEY_CARET_MOVE_DOWN,

    KeyTypeCount
};


class WebViewClientImpl;
class WebViewManager;

class WebView {
public:
    friend class WebViewClientImpl;
    friend class WebViewManager;

    WEBKIT_PUBLIC void drawRect(float x, float y, float w, float h, void* data, unsigned dataSize);
    WEBKIT_PUBLIC void setClipRect(int x, int y, int w, int h, bool pending = false);

    WEBKIT_PUBLIC void sendScrollEvent(ScrollEventType, int x = 0, int y = 0);
    WEBKIT_PUBLIC void sendMouseEvent(MouseEventType, MouseButtonType, int x, int y);
    WEBKIT_PUBLIC void sendKeyEvent(KeyEventType, KeyType, char ascii = 0, bool shift = false, bool ctrl = false, bool alt = false, bool win = false);
    WEBKIT_PUBLIC void sendKeyEvent2(KeyEventType, KeyType, char ascii = 0, bool shift = false, bool ctrl = false, bool alt = false, bool win = false, KeyDefaultBehavior = KeyDefaultBehaviorNone);
    WEBKIT_PUBLIC void sendHtmlEvent(HtmlEventType, const HtmlEventData* = 0);
    WEBKIT_PUBLIC void sendTouchEvent(const Manx::TouchEvent*);
    WEBKIT_PUBLIC void sendGestureEvent(unsigned type, int x, int y);

    WEBKIT_PUBLIC void loadUrl(const char *url);
    WEBKIT_PUBLIC void loadHtml(const char *html, const char *baseUrl);
    WEBKIT_PUBLIC void loadData(const char *data, unsigned long dataLen, const char *mimetype, const char *encoding, const char *baseUrl);
    WEBKIT_PUBLIC void loadArchive(const char *buf, unsigned long bufLen, const char *url);

    WEBKIT_PUBLIC void reload();
    WEBKIT_PUBLIC void stop();

    WEBKIT_PUBLIC void goBack();
    WEBKIT_PUBLIC void goForward();

    WEBKIT_PUBLIC void increaseTextSize();
    WEBKIT_PUBLIC void decreaseTextSize();

    WEBKIT_PUBLIC void resetTextSize();

    WEBKIT_PUBLIC void setCaretVisible(bool is_visible);
    WEBKIT_PUBLIC void setComposition(const char *compositionString, unsigned underlineFrom, unsigned underlineTo);
    WEBKIT_PUBLIC void confirmComposition(const char *compositionText, unsigned caretIndex);
    WEBKIT_PUBLIC void cancelComposition();
    WEBKIT_PUBLIC void exitComposition();
    WEBKIT_PUBLIC void clearText();

    WEBKIT_PUBLIC void setSelectedItemsPopupMenu(int index, bool is_end = false);
    WEBKIT_PUBLIC void getItemPopupMenu(int index);

    WEBKIT_PUBLIC void setWebViewSettingsScriptEnabled(bool is_enable);
    WEBKIT_PUBLIC void setWebGLEnabled(bool is_enable);
    WEBKIT_PUBLIC void setWebSecurityEnabled(bool is_enable);
    WEBKIT_PUBLIC void setDeveloperExtrasEnabled(bool is_enable);
    WEBKIT_PUBLIC void setUserAgent(const char*);
    WEBKIT_PUBLIC const char* userAgent();

    WEBKIT_PUBLIC void hitTest(Manx::Point& hitPoint, int type);
    WEBKIT_PUBLIC void imageBuffer();

    WEBKIT_PUBLIC void setUploadFile(const char* path, const char* name);

    WEBKIT_PUBLIC void setJavaScriptObj(WebViewJavaScriptObject* window);
    WEBKIT_PUBLIC void setWebViewSettingsCookieEnabled(bool is_enable);
    WEBKIT_PUBLIC void deleteAllCookies();
    WEBKIT_PUBLIC void setCookies(const char* url, const char* cookie);

    WEBKIT_PUBLIC void releaseTiles();
    WEBKIT_PUBLIC void overflowScroll(Manx::Point& hitPoint, int deltaX, int deltaY);
    WEBKIT_PUBLIC void setDefaultLayoutWidth(int);

    WEBKIT_PUBLIC void requestDownloadImage();
    WEBKIT_PUBLIC void requestDownloadImageData(int pos, int size);

    WEBKIT_PUBLIC void setGeolocationPermission(const char* origin, bool isAllowed);
    WEBKIT_PUBLIC void updateGeolocationPosition(const WebKit::WebViewGeolocationPosition*);

private:
    WebView(WebKit::WebViewCreateParam&);
    ~WebView();

    static bool isWebThread();

    void didFocusedNodeChangedWT();
    void didInputTextBluredWT();
    void checkInputMethodStateWT();
    void clearInputMethodInfoWT();
    void requestDownloadImageWT();
    void requestDownloadImageDataWT(int pos, int size);

    WebKit::WebView* m_impl;
    WebViewClientImpl* m_webViewClient;
    WebKit::InputMethodInfo m_inputMethodInfo;
};

} // namespace MXGlue

#ifndef BUILDING_WEBKIT
using namespace MXGlue;
#endif

#endif // WebView_h
